package gui_classes;



import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.io.Reader;

import javax.swing.*;

import java.io.Reader;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

import domain.*;
import java_persistence.*;
import resources.*;
import persistence.*;



public class GUI_Main
{
	// the frame for the application
	private static JFrame frame;
	private static JMenuBar menuBar;
	
	// These are all the panels at the highest level of hierarchy. These can be added directly to the frame's contentpane
	static LoginPanel lpanel;
	static PatientPage ppage;
	static NursePage npage;
	static DoctorPage dpage;
	static AdminPage apage;
	
	static RegistrationPanel rpage;
	static AddPatientPanel addpatientPage;
	static AddUserPanel adduserPage;
	static PatientAppointmentRequestPanel appointpage;
	static TreatmentScreen tscreen;
	static InvoiceScreen iscreen;
	static MedicalHistoryPage mscreen;
	static OrdersScreen oscreen;

	
	static IncomeChartPage ichartpage;
	static PatientChartPage pchartpage;
	
	static ViewPatientPage viewpinfo;
	 static ViewUserPage viewuinfo;
	
//	private static JPanel pviewpanel;
	private static JPanel uviewpanel;
	
	// these panels are put into other panels
	private static UsersPagePanel upanel;
	private static PatientsPagePanel ppanel;
	private static PatientsPageTwoPanel ppanel2;
	private static NursePanel npanel;
	private static DoctorPanel dpanel;
//	static CalendarPanel cpanel; // still need to work on this
	
	
	// these variables are used to make sure the GUI is running until it is supposed to exit.
	private static boolean pause;
	private static boolean exit;
	
	// this is the database session used in all our classes
	private static SqlSession session = null;
	
	/**
	 * This method sets up the frame for the GUI application
	 * along with the menu bar.
	 */
	public static void setUpStart()
	{

		// frame for GUI application
		frame = new JFrame("Georgia Tech Hospital Software System");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// Menu bar for GUI application
		menuBar = new JMenuBar();
		frame.getContentPane().add(menuBar, BorderLayout.NORTH);
		
		// Buttons on the menu bar. They are visible from every panel
		JButton btnBack = new JButton("Go Back");
		btnBack.addActionListener(new BackListener());
		menuBar.add(btnBack);
			
	
		JButton btnLogOut = new JButton("Log Out");
		btnLogOut.addActionListener(new LogoutListener());
		menuBar.add(btnLogOut); 
		
		// adds a dummy JPanel
		frame.getContentPane().add(new JPanel());
	}
	
	/**
	 * This method displays the login screen and performs user
	 * authentication operations
	 */
	public static void start()
	{
		// initialize login panel, set its previous page, and display it
		lpanel = new LoginPanel();
		lpanel.setPrevious(lpanel);
		lpanel.display();
				
		// loops until logged in
		waitForResponse();
		
		// Authenticates User. Checks the array in lpanel for login data input by user
		if( authenticateUser(lpanel.getArr()[0], lpanel.getArr()[1]))
		{
			// Retrieves all users from database. Will be used to see what type of user has logged in.
			// Assume patient
			boolean patient = true;
			List<Doctor> doctors = session.getMapper(DoctorMapper.class).get_doctors();
			List<Nurse> nurses = session.getMapper(NurseMapper.class).get_nurses();
			List<SystemAdministrator> sas = session.getMapper(SystemAdministratorMapper.class).get_sysadmins();
			
			// Creates a User object for the logged in user
			User cur_user = session.getMapper(UserMapper.class).get_user_by_username(lpanel.getArr()[0]);
			System.out.println("Logged in user: " + cur_user.getName() + "."); // and prints the name of the logged in user.
			
			// Loops through the lists to determine what type of user has logged in
			for( Doctor i: doctors) {
				if( i.getUsername().equals(cur_user.getUsername())) {
					System.out.println("is a doctor with user name " + cur_user.getUsername());
					patient = false;
					
					dpage = new DoctorPage(i);
					// Doctor Window
					dpage.display();
				}
			}
			
			
			for( Nurse i: nurses) {
				if( i.getUsername().equals(cur_user.getUsername())) {
					System.out.println("is a nurse");
					patient = false;
					
					npage = new NursePage(i);
					// Nurse Window
					npage.display();
				}
			}
			
			for( SystemAdministrator i: sas) {
				if( i.getUsername().equals(cur_user.getUsername())) {
					System.out.println("is a sysadmin");
					patient = false;
					
					apage = new AdminPage(i);
					
					// SysAdmin Window
					apage.display();
				}
			}
			
			if ( patient ) {
				/*
				 * Joseph: This code block is suppossed to make a Patient object called cur_patient and display
				 * the page appropriate for it. Right now I am unable to retrieve a Patient object from the database
				 * so I decided to use an alternate method (Using the for loop)
				 * 
				 * However, I would rather use session.getMapper(PatientMapper.class).get_patient_by_username();
				 * Can you see if that method works properly?
				 * 
				 * Pratik: It didn't.  I forgot something dumb, and I think I fixed it.  Leave this code in comments
				 * in case it doesn't work, but you should be ale to use the line above.  
				 *   
				 */
				Patient cur_patient = session.getMapper(PatientMapper.class).get_patient_by_username(lpanel.getArr()[0]);
				System.out.println("Logged in person is assumed to be a patient with usernamename " + lpanel.getArr()[0]);
							
				if(cur_patient.getActive_account())
				{
					ppage = new PatientPage(cur_patient);
					// Patient Window
					ppage.display();
				}
				else
				{
					JOptionPane.showMessageDialog(null, "Your account has been suspended. Contact your system administrator"); 

				}
			}			
		} // authentication  end if
		else {
			// this displays the Dialog Box that says username and password is not valid
			JOptionPane.showMessageDialog(null, "Your username and password is not valid. Try again."); 
		}
		
	}
	
	
	/**
	 * Replaces the panel in the frame with the passed in panel
	 * @param replacingPanel The panel that you want in the frame
	 */
	public static void replacePanel(JPanel replacingPanel)
	{
		frame.setVisible(false);
		frame.getContentPane().remove(1); // does not remove all things for some reason?
		
	//	frame.getContentPane().removeAll();
	//	frame.getContentPane().add(menuBar);
		
		frame.getContentPane().add(replacingPanel);
		frame.pack();
		frame.setVisible(true);
	}
	
	/*
	 * Used in login window to stall program until user logs in.
	 */
	public static void waitForResponse()
	{
		pause = false;
		while(!pause)
		{
			System.out.print("");
		}
		return;
	}
	
	/*
	 * Setter for the pause variable
	 * @param arg The boolean argument to set pause
	 */
	public static void setPause(boolean arg)
	{
		pause = arg;
	}
	
	public static void setExit(boolean arg)
	{
		exit = arg;
	}
	
	/*
	 * Returns the database session instance
	 */
	public static SqlSession getSession()
	{
		return session;
	}
	
	public static JFrame getFrame()
	{
		return frame;
	}
	
	public static DERPBase getRPage()
	{
		return rpage;
	}
	
	public static LoginPanel getLPanel()
	{
		return lpanel;
	}
	
	/*
	 * Authenticates a user based on username and password
	 */
	public static boolean authenticateUser(String uName, String pass)
	{
		if( lpanel.getArr()[1].equals(session.getMapper(UserMapper.class).get_password_by_username(lpanel.getArr()[0]))) {
			return true;
		}
		else
			return false;
	}
	
	/*
	 * Establishes a connection to mysql database
	 */
	public static void establishDBConnection()
	{
		String myBatis_config = "resources/mybatis-config.xml";
		Reader config_reader;
		try {
			config_reader = Resources.getResourceAsReader(myBatis_config);
			SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(config_reader);
			session = sessionFactory.openSession();
		} catch (IOException e) {
			System.out.println("Caught Exception: " + e.getMessage() );
		} 
	}
	
	/*
	 * Main method for entire program
	 */
	public static void main(String[] args)
	{
		
		// This will establish the database connection.
		establishDBConnection(); 

		// sets up the window frame
		setUpStart();
		
		// sets up the login screen 
		start();
			
		
	} // end of main
	
	/*
	 * Private class that handles listener for "Back" Button
	 */
	private static class BackListener implements ActionListener{
		public void actionPerformed(ActionEvent event){
			((DERPBase) GUI_Main.frame.getContentPane().getComponent(1)).displayPrev();
		}
	}
	
	/*
	 * Private class that handles listener for "Logout" Button
	 */
	private static class LogoutListener implements ActionListener{
		public void actionPerformed(ActionEvent event){
	//		GUI_Main.lpanel = new LoginPanel();
			replacePanel(GUI_Main.lpanel);
	//		GUI_Main.lpanel = null;
			
	/*		for(int i =GUI_Main.getFrame().getComponents().length; i==0; i--)
			{
				GUI_Main.getFrame().getContentPane().remove(i);
			} */

			GUI_Main.start();
		}
	}
} // end program
  